﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace ShadowGame
{
    public class GameComponent
    {
        protected Vector2 worldPosition;
        protected Vector2 velocity;
        //protected float angle = 0.0f;
        protected int frameWidth;
        protected int frameHeight;

        protected Vector2 prevPosition;
        protected bool flipped = false;
        protected bool onGround = true;
        protected bool enabled;

        protected Rectangle collisionRectangle;
        protected int collideWidth;
        protected int collideHeight;
        protected bool codeBasedBlocks = true;

        protected float drawDepth = 0.85f;
        protected Dictionary<string, Animation> animations = new Dictionary<string, Animation>();
        protected string currentAnimation;
        private List<Brick> bricks;

        public GameComponent(List<Brick> bricks)
        {
            this.bricks = bricks;
        }

        public string CurrentAnimation { get { return currentAnimation; } }
        public bool Enabled
        {
            get { return enabled; }
            set { enabled = value; }
        }

        public Vector2 WorldPosition
        {
            get { return worldPosition; }
            set { worldPosition = value; }
        }

        public Vector2 WorldCenter
        {
            get
            {
                return new Vector2(
                    (int)WorldPosition.X + (int)(frameWidth / 2),
                    (int)WorldPosition.Y + (int)(frameHeight / 2));
            }
        }

        public Rectangle WorldRectangle
        {
            get
            {
                return new Rectangle(
                    (int)WorldPosition.X,
                    (int)WorldPosition.Y,
                    frameWidth,
                    frameHeight);
            }
        }

        public Rectangle CollisionRectangle
        {
            get
            {
                return new Rectangle(
                    (int)WorldPosition.X ,
                    (int)WorldPosition.Y ,
                    collisionRectangle.Width,
                    collisionRectangle.Height);
            }
            set { collisionRectangle = value; }
        }

        private void updateAnimation(GameTime gameTime)
        {
            if (animations.ContainsKey(currentAnimation))
            {
                if (animations[currentAnimation].FinishedPlaying)
                {
                    PlayAnimation(animations[currentAnimation].NextAnimation);
                }
                else
                {
                    animations[currentAnimation].Update(gameTime);
                }
            }
        }

        /*private void updateAngle()
        {
            if (speed != Vector2.Zero)
            {
                angle = (float)Math.Atan2(
                    worldPosition.Y - prevPosition.Y,
                    worldPosition.X - prevPosition.X) + MathHelper.PiOver2;
            }

        }*/

        public void PlayAnimation(string name)
        {
            if (name != null && animations.ContainsKey(name))
            {
                currentAnimation = name;
                animations[name].Play();
            }
        }

        public virtual void Update(GameTime gameTime)
        {
            if (!Enabled)
                return;

            prevPosition = worldPosition;

            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

            updateAnimation(gameTime);
            if (velocity.Y != 0)
            {
                onGround = false;
            }
            Vector2 moveAmount = velocity * elapsed;
            moveAmount = horizontalCollisionTest(moveAmount);
            Vector2 newPosition = WorldPosition + moveAmount;
            newPosition = new Vector2(
                MathHelper.Clamp(newPosition.X, 0, Camera.WorldRectangle.Width - frameWidth),
                MathHelper.Clamp(newPosition.Y, 0, Camera.WorldRectangle.Height - frameHeight));

            WorldPosition = newPosition;

            //updateAngle();
        }

        public virtual void Draw(SpriteBatch spriteBatch)
        {
            if (!Enabled)
                return;

            if (animations.ContainsKey(currentAnimation))
            {
                SpriteEffects effect = SpriteEffects.None;
                if (flipped)
                {
                    effect = SpriteEffects.FlipHorizontally;
                }
                Rectangle screenRectangle = Camera.WorldToScreen(WorldRectangle);

                /*spriteBatch.Draw(
                    animations[currentAnimation].Texture,
                    new Rectangle(screenRectangle.X + (frameWidth / 2), screenRectangle.Y + (frameHeight / 2), screenRectangle.Width, screenRectangle.Height),
                    animations[currentAnimation].FrameRectangle,
                    Color.White,
                    angle,
                    new Vector2(frameWidth / 2, frameHeight / 2),
                    effect,
                    drawDepth);*/
                spriteBatch.Draw(
                    animations[currentAnimation].Texture,
                    Camera.WorldToScreen(WorldRectangle),
                    animations[currentAnimation].FrameRectangle,
                    Color.White, 0.0f, Vector2.Zero, effect, drawDepth);
            }
        }

        private Vector2 horizontalCollisionTest(Vector2 moveAmount)
        {
            if (worldPosition.Y + WorldRectangle.Height >= BackgroundManager.Height)
            {
                onGround = true;
                velocity.Y = 0;
            }

            if (bricks != null)
            {
                foreach (Brick brick in bricks)
                {
                    if (CollisionRectangle.Intersects(brick.CollisionRectangle))
                    {
                        /*if (worldPosition.Y + WorldRectangle.Height < brick.worldPosition.Y + (brick.WorldRectangle.Height / 4) && moveAmount.Y < 0)
                        {
                            if ((worldPosition.X) < brick.worldPosition.X && moveAmount.X > 0)
                            {
                                moveAmount.X = 0;
                                velocity.X = 0;
                            }
                            if ((worldPosition.X) > brick.worldPosition.X && moveAmount.X < 0)
                            {
                                moveAmount.X = 0;
                                velocity.X = 0;
                            }
                            velocity.Y = 0;
                            moveAmount.Y = 5;
                        }
                        else*/
                        if (worldPosition.Y > brick.worldPosition.Y + brick.WorldRectangle.Height && moveAmount.Y < 0)
                        {
                            if ((worldPosition.X) < brick.worldPosition.X && moveAmount.X > 0)
                            {
                                moveAmount.X = 0;
                                velocity.X = 0;
                            }
                            if ((worldPosition.X) > brick.worldPosition.X && moveAmount.X < 0)
                            {
                                moveAmount.X = 0;
                                velocity.X = 0;
                            }
                            return moveAmount;
                        }
                        else if (worldPosition.Y + WorldRectangle.Height < brick.worldPosition.Y + (brick.WorldRectangle.Height/4) && moveAmount.Y >= 0)
                        {
                            onGround = true;
                            moveAmount.Y = 0;
                            velocity.Y = 0;
                        }
                        else
                        {
                            //if (moveAmount.Y < 0)
                            //onGround = true;

                            //velocity.Y = 0;
                            //moveAmount.Y = 5;

                            if ((worldPosition.X) < brick.worldPosition.X && moveAmount.X > 0)
                            {
                                moveAmount.X = 0;
                                velocity.X = 0;
                            }
                            if ((worldPosition.X) > brick.worldPosition.X && moveAmount.X < 0)
                            {
                                moveAmount.X = 0;
                                velocity.X = 0;
                            }
                        }
  
                    }
                }
            }

            return moveAmount;
        }
    }
}
